package com.lrkj.payfee.service.impl;

import com.lrkj.common.constant.FeeConstants;
import com.lrkj.common.utils.DateUtils;
import com.lrkj.common.utils.SecurityUtils;
import com.lrkj.common.utils.uuid.IdUtils;
import com.lrkj.framework.utils.SerialNumUtil;
import com.lrkj.payfee.domain.*;
import com.lrkj.payfee.factory.PayFeeFactory;
import com.lrkj.payfee.mapper.CopyRoomMapper;
import com.lrkj.payfee.service.*;
import com.lrkj.payfee.vo.CopyRoomVo;
import com.lrkj.property.domain.Room;
import com.lrkj.property.service.IRoomService;
import com.lrkj.system.service.IOrgTreeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 抄房间仪表Service业务层处理
 *
 * @author yajun_ren
 * @date 2021-07-30
 */
@Service
public class CopyRoomServiceImpl implements ICopyRoomService {
    @Autowired
    private CopyRoomMapper copyRoomMapper;

    @Autowired
    private IOrgTreeService orgTreeService;

    @Autowired
    private IRoomMeterService roomMeterService;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IGenerateService generateService;

    @Autowired
    private IRoomNormService roomNormService;

    @Autowired
    private IChargeNormService chargeNormService;

    @Autowired
    private PayFeeFactory payFeeFactory;

    @Autowired
    private IRuleCostService ruleCostService;


    /**
     * 查询抄房间仪表
     *
     * @param copyId 抄房间仪表ID
     * @return 抄房间仪表
     */
    @Override
    public CopyRoom selectCopyRoomById(String copyId) {
        return copyRoomMapper.selectCopyRoomById(copyId);
    }

    /**
     * 查询抄房间仪表列表
     *
     * @param copyRoom 抄房间仪表
     * @return 抄房间仪表
     */
    @Override
    public List<CopyRoom> selectCopyRoomList(CopyRoom copyRoom) {
        return copyRoomMapper.selectCopyRoomList(copyRoom);
    }

    /**
     * 新增抄房间仪表
     *
     * @param copyRoom 抄房间仪表
     * @return 结果
     */
    @Override
    public int insertCopyRoom(CopyRoom copyRoom) {
        copyRoom.setCopyId(IdUtils.simpleUUID());
        copyRoom.setCreateBy(SecurityUtils.getUsername());
        copyRoom.setCreateTime(DateUtils.getNowDate());
        copyRoom.setStatus(FeeConstants.copy_romm_status_10);
        this.setUnitInfo(copyRoom);
        return copyRoomMapper.insertCopyRoom(copyRoom);
    }

    /**
     * 修改抄房间仪表
     *
     * @param copyRoom 抄房间仪表
     * @return 结果
     */
    @Override
    public int updateCopyRoom(CopyRoom copyRoom) {
        copyRoom.setUpdateBy(SecurityUtils.getUsername());
        copyRoom.setUpdateTime(DateUtils.getNowDate());
        this.setUnitInfo(copyRoom);
        return copyRoomMapper.updateCopyRoom(copyRoom);
    }

    private void setUnitInfo(CopyRoom bean) {
        Room room = roomService.selectRoomById(bean.getRoomId());
        bean.setAncestors(room.getAncestors() + "," + room.getId());
        bean.setDeptId(room.getDeptId());
        //orgTreeService.insertOrgTree(bean.getCopyId(),room.getOwnerVo().getOwnerName(), bean.getCopyId(), OrgConstants.copy, room.getAncestors());
    }

    /**
     * 批量删除抄房间仪表
     *
     * @param copyIds 需要删除的抄房间仪表ID
     * @return 结果
     */
    @Override
    public int deleteCopyRoomByIds(String[] copyIds) {
        ruleCostService.deleteRuleCostByCopyId(copyIds);
        orgTreeService.deleteOrgTreeByIds(copyIds);
        return copyRoomMapper.deleteCopyRoomByIds(copyIds);
    }

    /**
     * 删除抄房间仪表信息
     *
     * @param copyId 抄房间仪表ID
     * @return 结果
     */
    @Override
    public int deleteCopyRoomById(String copyId) {
        orgTreeService.deleteOrgTreeById(copyId);
        return copyRoomMapper.deleteCopyRoomById(copyId);
    }

    @Override
    public int doSaveList(List<CopyRoom> batchBean) {
        List<CopyRoom> saveBeans = new ArrayList<>();
        if (batchBean.size() > 500) {
            for (int i = 0; i < batchBean.size(); i++) {
                if ((i + 1) % 500 == 0) {
                    saveBeans.add(batchBean.get(i));
                    copyRoomMapper.doSaveList(saveBeans);
                    saveBeans.clear();
                } else {
                    saveBeans.add(batchBean.get(i));
                }
            }
            if (null != saveBeans && saveBeans.size() > 0) {
                copyRoomMapper.doSaveList(saveBeans);
            }
        }
        for (CopyRoom copyRoom : saveBeans) {
            this.setUnitInfo(copyRoom);
        }
        return 1;
    }

    @Override
    public CopyRoomVo lastRoomReading(String rometerId) {
        CopyRoomVo resultBean = new CopyRoomVo();
        //1、查看房间有没有抄表记录
        CopyRoom copyRoom = copyRoomMapper.lastRoomReading(rometerId);
        if (null != copyRoom) {
            resultBean.setLastReading(copyRoom.getTheReading()); //最后一次读数
            resultBean.setLastTime(copyRoom.getReadingTime()); //最后一次读取时间
            resultBean.setOwnerId(copyRoom.getOwnerId()); //客户ID
            resultBean.setKindId(copyRoom.getKindId()); //仪表种类ID
            resultBean.setTicket(copyRoom.getTicket());
        } else {
            //2、没有抄表记录,去查询房间仪表获取初始记录
            RoomMeter roomMeter = roomMeterService.selectRoomMeterById(rometerId);
            resultBean.setLastReading(roomMeter.getLastReading()); //上一次读数
            resultBean.setLastTime(roomMeter.getLastTime()); //上一次读取时间
            resultBean.setOwnerId(roomMeter.getOwnerId()); //客户ID
            resultBean.setKindId(roomMeter.getKindId()); //仪表种类ID
            resultBean.setTicket(roomMeter.getTicket().toString());
        }
        return resultBean;
    }

    /***
     * 批量生成房屋仪表费用
     * **/
    @Override
    @Transactional
    public Map<String, Object> batchPayfee(CopyRoomVo copyRoomVo) {
        Map<String, Object> result = new HashMap<>();
        List<String> errorMsg = new ArrayList<>();
        List<String> successMsg = new ArrayList<>();
        List<RuleCost> savaRuleCosts = new ArrayList<>();
        List<CopyRoom> updateCopyRooms = new ArrayList<>();
        //获取房屋收费标准
        Map<String, RoomNorm> roomNormMap = new HashMap<>();
        List<RoomNorm> roomNorms = roomNormService.selectKindRoomNorm(copyRoomVo.getBusinessId());
        roomNorms.stream().forEach(x -> {
            //房屋仪表种类
            String key = x.getRoomId() + "-" + x.getKindId();
            roomNormMap.put(key, x);
        });

        //获取收费标准
        Map<String, ChargeNorm> chargeNormMap = new HashMap<>();
        List<ChargeNorm> chargeNorms = chargeNormService.selectChargeNormList(new ChargeNorm());
        chargeNorms.stream().forEach(x -> {
            chargeNormMap.put(x.getChargeId(), x);
        });
        //1、查询未生成的房间抄表记录
        CopyRoom eg = new CopyRoom();
        eg.setNodeId(copyRoomVo.getBusinessId());
        eg.setStatus(FeeConstants.copy_romm_status_10);
        List<CopyRoom> copyRooms = copyRoomMapper.selectCopyRoomList(eg);
        for (CopyRoom copyRoom : copyRooms) {
            //房屋仪表收费标准 key
            String roomNormKey = copyRoom.getRoomId() + "-" + copyRoom.getKindId();
            if (!roomNormMap.containsKey(roomNormKey)) {
                errorMsg.add("房屋[" + copyRoom.getRoomName() + "]没有绑定[" + copyRoom.getKindName() + "]仪表收费标准!");
                continue;
            } else {
                //收费标准
                RoomNorm roomNorm = roomNormMap.get(roomNormKey);
                savaRuleCosts.add(this.ruleCostFactory(copyRoom, roomNorm, chargeNormMap.get(roomNorm.getChargeId())));
                successMsg.add("房屋[" + copyRoom.getRoomName() + "]-[" + copyRoom.getKindName() + "]仪表费用创建成功!");
                copyRoom.setStatus(FeeConstants.copy_romm_status_20);
                copyRoom.setUpdateTime(DateUtils.getNowDate());
                copyRoom.setUpdateBy(SecurityUtils.getUsername());
                updateCopyRooms.add(copyRoom);
            }
        }
        //批量更新抄表记录状态
        if(null != updateCopyRooms && updateCopyRooms.size() > 0){
            copyRoomMapper.bathUpdateStatus(updateCopyRooms);
        }
        ruleCostService.doSaveList(savaRuleCosts);
        result.put("errorMsg", errorMsg);
        result.put("successMsg", successMsg);
        return result;
    }

    /***
     * 费用工厂
     *
     * **/
    private RuleCost ruleCostFactory(CopyRoom copyRoom, RoomNorm roomNorm, ChargeNorm chargeNorm) {
        RuleCost ruleCost = new RuleCost();
        ruleCost.setCostId(IdUtils.simpleUUID()); //主键ID
        ruleCost.setCopyId(copyRoom.getCopyId()); //抄表记录ID
        ruleCost.setRoomId(copyRoom.getRoomId());//所属房间
        ruleCost.setDeptId(copyRoom.getDeptId()); //所属机构
        ruleCost.setOwnerId(copyRoom.getOwnerId()); //业主id
        ruleCost.setCostNo(SerialNumUtil.getNo(FeeConstants.meter_cost_key));  //单据号
        ruleCost.setProjectId(roomNorm.getProjectId());//收费类型
        ruleCost.setChargeId(roomNorm.getChargeId());//收费项目
        ruleCost.setNormId(roomNorm.getNormId());//收费标准
        ruleCost.setReceivableTime(DateUtils.getNowDate());//应收日期
        //金额
        chargeNorm.setPrices(roomNorm.getPrices());
        BigDecimal moneys = payFeeFactory.computingMeterMoney(roomNorm, chargeNorm, copyRoom.getChargedLine());
        ruleCost.setPrices(chargeNorm.getPrices());   //单价
        ruleCost.setMoneys(moneys);//金额
        ruleCost.setReceivableMoney(moneys);//应收金额
        ruleCost.setQueenMoney(moneys);//优惠后金额
        ruleCost.setSpecialMoney(new BigDecimal(0));  //优惠金额
        ruleCost.setHaveMoney(new BigDecimal(0));//已收金额
        ruleCost.setAmountOwed(moneys);  //欠费金额
        ruleCost.setAmountAmount(new BigDecimal(0));//冲抵金额
        ruleCost.setBeginTime(copyRoom.getLastTime());//开始时间
        ruleCost.setFinishTime(copyRoom.getReadingTime());//结束时间
        ruleCost.setChargedLine(copyRoom.getChargedLine());//计费行度
        ruleCost.setPaymentCycle(DateUtils.dateTime(ruleCost.getFinishTime()));//缴费截止日
        ruleCost.setAncestors(roomNorm.getAncestors()); //祖级ID
        ruleCost.setStatus(FeeConstants.charge_status_10001); //收费状态
        return ruleCost;
    }


}
